home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / overxms.exe / OVRXMS.PAS < prev    next >
Pascal/Delphi Source File  |  1993-07-09  |  8KB  |  325 lines

  1. {$O-}
  2. unit OvrXMS;
  3.  
  4. { OVERXMS 1.2 - Loads overlays in XMS.  }
  5. {Assembler OBJ version written by Wilbert van Leijen }
  6.  
  7. { This Built In Assembler version 1/03/93 }
  8. { adapted by Arnold Bailey [72020,1376] BIX abailey }
  9.  
  10. { Version 1.1 Includes Bug Fix for DRDOS 6 }
  11.  
  12. { Version 1.2 Method for determining total XMS need in AllocateXMS         }
  13. {             was different than the method used by CopyUnitToXMS.         }
  14. {             Since memory is allocate in 1k chunks there was rarely       }
  15. {             a problem unless the total size fell just below a 1k boundary}
  16. {             Changed AllocateXMS to take into account word size           }
  17. {             moves only to and from XMS.                                  }
  18.  
  19. { Unofficial version                                                       }
  20. {             Exit procedure in OvrXms was not declared as 'FAR'.  This    }
  21. {             could lead to the program bombing when the exit proc chain   }
  22. {             was traversed.   --  John Leier [70711,3456]                 }
  23.  
  24. Interface
  25. uses Overlay;
  26.  
  27. Const
  28.   ovrNoXMSDriver = -7;                 { No XMS driver installed }
  29.   ovrNoXMSMemory = -8;                 { Insufficient XMS memory available }
  30.  
  31. Procedure OvrInitXMS;
  32.  
  33. Implementation
  34.  
  35. type
  36.   XMSMoveType=
  37.     record
  38.       BlkSize    : LongInt;
  39.       SrcHandle  : word;
  40.       SrcOffset  : LongInt;
  41.       DestHandle : word;
  42.       DestOffset : LongInt;
  43.     end;
  44.  
  45.   OvrHeader =
  46.     record
  47.       ReturnAddr   : pointer;
  48.       FileOfs      : LongInt;
  49.       CodeSize     : word;
  50.       FixUpSize    : word;
  51.       EntryPts     : word;
  52.       CodeListNext : word;
  53.       LoadSeg      : word;
  54.       Reprieved    : word;
  55.       LoadListNext : word;
  56.       XMSOffset    : LongInt;
  57.       UserData     : array[0..2] of word;
  58.     end;
  59.  
  60. const
  61.   XMSDriver    : pointer = NIL;
  62.   ExitSave     : pointer = NIL;
  63.   OvrXMSHandle : word    = $FFFF;
  64.  
  65. var
  66.   XMSMove      : XMSMoveType;
  67.  
  68. procedure OvrXMSExit; FAR;   { !!! Ver 1.2a bug fix  [JL] }
  69.  
  70.   begin
  71.     ExitProc:=ExitSave;
  72.     asm
  73.       mov dx,OvrXMSHandle
  74.       mov ah,0Ah
  75.       call [XMSDriver]
  76.     end;
  77.   end;
  78.  
  79. procedure AllocateXMS; assembler;
  80.  
  81.         {Determine the size of the code block to allocate}
  82.         {Walk the CodeListNext chain}
  83.         {Store the total codesize in DX:AX}
  84. asm
  85.         xor  ax,ax
  86.         mov  dx,ax
  87.         mov  bx,[OvrCodeList]
  88. @@1:    add  bx,[Prefixseg]
  89.         add  bx,10h
  90.         mov  es,bx
  91.  
  92. {** Ver 1.2 Bug Fix }
  93.         mov  cx,es:[OvrHeader.CodeSize]
  94.         test cx,1                       { Test for odd number of bytes}
  95.         jz   @@2
  96.         inc  cx                         { Even number of bytes only }
  97. @@2:    add  ax,cx
  98. {** Ver 1.2 Bug Fix }
  99.  
  100.         adc  dx,0
  101.         mov  bx,es:[OvrHeader.CodeListNext]
  102.         or   bx,bx
  103.         jnz  @@1
  104.  
  105.         { Obtain number of kilobytes to allocate}
  106.  
  107.         mov  bx,1024
  108.         div  bx
  109.         xchg dx,ax
  110.         inc  dx
  111.  
  112.         { Allocate the block }
  113.  
  114.         mov  ah,9
  115.         call [XMSDriver]
  116.         or   ax,ax
  117.         jz   @@3
  118.         mov  OvrXMSHandle,dx
  119. @@3:
  120. end;
  121.  
  122. function XMSReadFunc(OvrSeg : word):integer; far;
  123.  
  124.   begin
  125.     asm
  126.         mov  es,OvrSeg
  127.         mov  ax,es:[OvrHeader.CodeSize]
  128.         mov  word ptr [XMSMove.BlkSize],ax
  129.  
  130.         xor  ax,ax
  131.         mov  word ptr [XMSMove.BlkSize+2],ax          { zero high word}
  132.         mov  [XMSMove.DestHandle],ax                  { zero dest Handle }
  133.         mov  word ptr [XMSMove.DestOffset],ax         { zero destination offset}
  134.  
  135.         mov  ax,[OvrXMSHandle]
  136.         mov  [XMSMove.SrcHandle],ax
  137.  
  138.         mov  ax,word ptr es:[OvrHeader.XMSOffset]
  139.         mov  word ptr [XMSMove.SrcOffset],ax
  140.         mov  ax,word ptr es:[OvrHeader.XMSOffset+2]
  141.         mov  word ptr [XMSMove.SrcOffset+2],ax
  142.  
  143.         mov  ax,es:[OvrHeader.LoadSeg]
  144.         mov  word ptr [XMSMove.DestOffset+2],ax
  145.         mov  ah,0bh
  146.         lea  si,XMSMove
  147.         call [XMSDriver]
  148.         or   ax,ax
  149.         jz   @@1
  150.         dec  ax
  151.         jmp  @@2
  152. @@1:    mov  ax,OvrIOError
  153. @@2:    mov  @Result,ax
  154.     end;
  155.   end;
  156.  
  157. procedure CopyUnitToXMS; assembler;
  158.  
  159. asm
  160.         mov  dx,es:[OvrHeader.CodeSize]
  161.         test dx,1
  162.         jz   @@1
  163.         inc  dx
  164.         inc  es:[OvrHeader.CodeSize]
  165.  
  166. @@1:    mov  word ptr [XMSMove.BlkSize],dx
  167.         xor  ax,ax
  168.         mov  word ptr [XMSMove.BlkSize+2],ax
  169.         mov  [XMSMove.SrcHandle],ax
  170.         mov  word ptr [XMSMove.SrcOffset],ax
  171.         mov  ax,[OvrHeapOrg]
  172.         mov  word ptr [XMSMove.SrcOffset+2],ax
  173.         mov  ax,[OvrXMSHandle]
  174.         mov  [XMSMove.DestHandle],ax
  175.         mov  word ptr [XMSMove.DestOffset],di
  176.         mov  word ptr [XMSMove.DestOffset+2],bx
  177.         mov  ah,0bh
  178.         lea  si,XMSMove
  179.  
  180.         push bx
  181.         call [XMSDriver]
  182.         pop  bx
  183.  
  184.         add  di,dx
  185.         adc  bx,0
  186.         or   ax,ax
  187.         jz   @@2
  188.         clc
  189.         jmp  @@3
  190. @@2:    stc
  191. @@3:
  192. end;
  193.  
  194. procedure OvrXMSLoad;
  195.  
  196.   begin
  197.  
  198. {  Walk the CodeList chain }
  199. {  First segment is PrefixSeg+10h+OvrCodeList }
  200. {  Push each element of overlaid unit list on the stack }
  201. {  Keep the size of the linked list in CX }
  202.       asm
  203.         MOV    AX, [OvrCodeList]
  204.         XOR    CX, CX
  205. @@1:    ADD    AX, [PrefixSeg]
  206.         ADD    AX, 10h
  207.         MOV    ES, AX
  208.         PUSH   AX
  209.         INC    CX
  210.         MOV    AX, ES:[OvrHeader.CodeListNext]
  211.         OR     AX, AX
  212.         JNZ    @@1
  213.  
  214. {  Loop:}
  215. {    Pop each element of the overlaid unit list from the stack }
  216.  
  217.         XOR    BX, BX
  218.         XOR    DI, DI
  219. @@2:    POP    ES
  220.         PUSH   CX
  221.         MOV    AX, [OvrHeapOrg]
  222.         MOV    ES:[OvrHeader.LoadSeg], AX
  223.         MOV    Word Ptr ES:[OvrHeader.XmsOffset+2], BX
  224.         MOV    Word Ptr ES:[OvrHeader.XmsOffset], DI
  225.  
  226. {  Load overlay from disk }
  227.  
  228.         PUSH   BX
  229.         PUSH   DI
  230.         PUSH   ES
  231.         PUSH   ES
  232.         CALL   [OvrReadBuf]
  233.         POP    ES
  234.         POP    DI
  235.         POP    BX
  236.  
  237. {  Flag unit as 'unloaded'; check return code }
  238.  
  239.         MOV    ES:[OvrHeader.LoadSeg], 0
  240.         NEG    AX
  241.         JC     @@3
  242.  
  243.         CALL   CopyUnitToXms
  244.         JC     @@3
  245.  
  246.         POP    CX
  247.         LOOP   @@2
  248.  
  249. @@3:
  250.     end;
  251.   end;
  252.  
  253.  
  254. procedure OvrInitXMS; assembler;
  255.  
  256. {  Make sure the file's been opened}
  257.  
  258. asm
  259.         XOR    AX, AX
  260.         CMP    AX, [OvrDOSHandle]
  261.         JNE    @@1
  262.         DEC    AX                      { ovrError }
  263.         JMP    @@5
  264.  
  265. {  Check presence of XMS driver }
  266.  
  267. @@1:    MOV    AX, 4300h
  268.         INT    2Fh
  269.         CMP    AL, 80h
  270.         JE     @@2
  271.         MOV    AX, ovrNoXmsDriver
  272.         JMP    @@5
  273.  
  274. {  Get XMS driver's entry point }
  275.  
  276. @@2:    MOV    AX, 4310h
  277.         INT    2Fh
  278.         MOV    Word Ptr [XmsDriver], BX
  279.         MOV    Word Ptr [XmsDriver+2], ES
  280.         CALL   AllocateXms
  281.         JNZ    @@3
  282.         MOV    AX, ovrNoXMSMemory
  283.         JMP    @@5
  284.  
  285. {  Load the overlay into XMS }
  286.  
  287. @@3:    CALL   OvrXmsLoad
  288.         JNC    @@4
  289.  
  290. {  An error occurred.  Release handle and XMS memory }
  291.  
  292.         MOV    DX, [OvrXmsHandle]
  293.         MOV    AH, 0Ah
  294.         CALL   [XmsDriver]
  295.         MOV    AX, ovrIOError
  296.         JMP    @@5
  297.  
  298. {  Close file }
  299.  
  300. @@4:    MOV    BX, [OvrDOSHandle]
  301.         MOV    AH, 3Eh
  302.         INT    21h
  303.  
  304. {  OvrReadBuf := XmsReadFunc }
  305.  
  306.         MOV    Word Ptr [OvrReadBuf], Offset XmsReadFunc
  307.         MOV    Word Ptr [OvrReadBuf+2], CS
  308.  
  309. {  ExitSave := ExitProc }
  310. {  ExitProc := OvrXmsExit }
  311.  
  312.         LES    AX, [ExitProc]
  313.         MOV    Word Ptr [ExitSave], AX
  314.         MOV    Word Ptr [ExitSave+2], ES
  315.         MOV    Word Ptr [ExitProc], Offset OvrXmsExit
  316.         MOV    Word Ptr [ExitProc+2], CS
  317.  
  318. {  Return result of initialisation }
  319.  
  320.         XOR    AX, AX
  321. @@5:    MOV    [OvrResult],AX
  322. end;
  323.  
  324. end.
  325.